package enemies 
{
	import collisions.Body;
	import collisions.LinkedList;
	import collisions.QuadTree;
	import collisions.World;
	import entities.Entity;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.Timer;
	import player.Player;
	import recorder.EntityStateRecorder;
	import recorder.RecordData;
	import renderers.Renderer;
	import collisions.PixelPerfectCollisionDetection;
	
	/**
	 * ...
	 * @author Gareth Williams
	 * todo: implement narrowphase physics for increased granularity
	 */
	public class Enemy extends Entity
	{
		//state machine properties
		private var state:Strategy = new Strategy();
		
		public var fireProbability:Number = 0.1;
		public var weaponStrength:int = 1; //different enemies will have different weapons
		
		//state properties recorder
		private var _recorder:EntityStateRecorder;
		
		public function Enemy(x:Number = 0, y:Number = 0, radius:Number = 10) 
		{
			collisionGroup = Constants.BULLET_GROUP | Constants.PLAYER_GROUP;
			speed = 1;
			
			super(x, y, radius);
			_recorder = new EntityStateRecorder(this);
			
			//test
			state.implementation = new SinePath(4,100);// new GeomPath(4, 100);
		}
		override public function destructor():void 
		{
			super.destructor();
		}
		public function receiveDamage(amount:int):void
		{
			this.percentHealth -= amount;
			//this.graphic.doHitAnimation();
			//this.graphic.doHealthAnimation(percentHealth);
			if (true == checkWhetherDead())
			{
				this.isAlive = false;
				//this.graphic.doDeathAnimation();
			}
		}
		override public function update():void //Entity
		{
			//apply recorded states
			_recorder.update();
			var data:RecordData = _recorder.retrieveDataAt(Main.timestep);
			data.applyTo(this);
			
			//making visible false removes from internal render engine
			if (false == isAlive)
			{
				Sprite(graphic).visible = false;
		//profiling
				World.removeBody(this);
			}
			else
			{
				Sprite(graphic).visible = true;
		//profiling
				World.addBody(this);
			}
			
			if (isAlive == false) return;
			
			//strategy
			var strategyCompleted:Boolean = state.perform(this);
		//profiling
			if (true == strategyCompleted && World.bodies[this])
			{
				World.removeBody(this);
			}
			/*
			if (strategyCompleted)
			{
				state.implementation = new GeomPath(3+int(Math.random()*7),100);
			}
			*/
		}
		//collision detection (broadphase)
		override public function processCollisionWith(collider:Body):void //Body
		{	
			this.isAlive = false;
		}
		override public function doRender():Boolean
		{
			return Sprite(graphic).visible;
		}
		//handlers
		//helpers
		private function checkWhetherDead():Boolean
		{
			return percentHealth <= 0;
		}
	}
}